/* 
 * File:   Dup.cpp
 * Author: Gab'z
 * 
 * Created on 31 mai 2012, 14:47
 */

#include "Dup.h"
#include "../../../Context.h"
#include "../../literal/Stack.h"
#include "../../../memento/EmptyMemento.h"

namespace calculator {

    Dup::Dup(const std::string name) : Operator(name) {
    }

    Dup::Dup(const Dup& orig) : Operator(orig._name) {
    }

    Dup::~Dup() {
    }

    Dup* Dup::clone() const {
        return new Dup(_name);
    }

    std::string Dup::isExecutable() const {
        if (Context::getInstance()->getCurrentStack()->empty()) return "Empty stack";
        return "";
    }

    const Memento* Dup::createMemento() const throw (CommandException) {
        if (Context::getInstance()->getCurrentStack()->empty()) throw CommandException("Empty stack");
        return new EmptyMemento(clone());
    }

    void Dup::restoreFromMemento(const Memento* memento) const throw (MementoException) {
        const EmptyMemento* emptyMemento = dynamic_cast<const EmptyMemento*> (memento);
        if (emptyMemento == 0) {
            std::string str = "Bad Memento type, expected : EmptyMemento, was ";
            str += typeid (*memento).name();
            throw MementoException(str);
        }
        Context::getInstance()->getCurrentStack()->pop();
    }

    void Dup::eval(Stack* stack) const throw (CommandException) {
        if (Context::getInstance()->getCurrentStack()->empty()) throw CommandException("Empty stack");
        Context::getInstance()->getCurrentStack()->push(Context::getInstance()->getCurrentStack()->top());
    }
}
